package com.dd.cloud.user.service.pres.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dd.cloud.common.constants.DrugsConstants;
import com.dd.cloud.common.constants.PharConstants;
import com.dd.cloud.common.constants.PresConstants;
import com.dd.cloud.common.enums.ZkExceptionEnum;
import com.dd.cloud.common.exception.ZekeException;
import com.dd.cloud.common.interceptor.UserInterceptor;
import com.dd.cloud.common.utils.*;
import com.dd.cloud.common.vo.LoginInfo;
import com.dd.cloud.user.DTO.hr.ReturnDrugList;
import com.dd.cloud.user.DTO.hst.HstDrugsResDTO;
import com.dd.cloud.user.DTO.xx.ResultResDTO;
import com.dd.cloud.user.DTO.yf.ReturnQueryDrugKlResultDTO;
import com.dd.cloud.user.entity.phar.Pharmacy;
import com.dd.cloud.user.entity.phar.PharmacyDocking;
import com.dd.cloud.user.entity.pres.DrugsModel;
import com.dd.cloud.user.feign.SearchFeignService;
import com.dd.cloud.user.mapper.pres.DrugsModelMapper;
import com.dd.cloud.user.req.drugs.ExcelAddDrugModel;
import com.dd.cloud.user.req.pres.DrugsModelAddReq;
import com.dd.cloud.user.req.pres.DrugsModelUpdateReq;
import com.dd.cloud.user.req.pres.PresPageReq;
import com.dd.cloud.user.res.pres.DrugsModelInfoListRes;
import com.dd.cloud.user.res.pres.DrugsModelManagePageRes;
import com.dd.cloud.user.res.pres.DrugsModelPageRes;
import com.dd.cloud.user.service.phar.IPharmacyDockingService;
import com.dd.cloud.user.service.phar.IPharmacyService;
import com.dd.cloud.user.service.pres.IDrugsDiscountService;
import com.dd.cloud.user.service.pres.IDrugsModelService;
import com.dd.cloud.user.vo.*;
import com.github.houbb.opencc4j.util.ZhConverterUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * <p>
 * 中药仓库表 服务实现类
 * </p>
 *
 * @author czg
 * @since 2022-05-09
 */
@Slf4j
@Service
public class DrugsModelServiceImpl extends ServiceImpl<DrugsModelMapper, DrugsModel> implements IDrugsModelService {
    @Autowired
    private IPharmacyService pharmacyService;
    @Autowired
    private IPharmacyDockingService pharmacyDockingService;
    @Autowired
    private IDrugsDiscountService drugsDiscountService;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private SearchFeignService searchFeignService;


    /**
     * 按照关键字查询药品
     *
     * @param keyword 关键字 药品名及拼音 药品别名及拼音
     * @return
     */
    @Override
    public List<DrugsModel> getDrugsModelListByKeyword(String keyword) {
        QueryWrapper<DrugsModel> qw = new QueryWrapper<>();

        if (StringUtils.isBlank(keyword)) {
            qw.lambda().eq(DrugsModel::getStatus, PresConstants.PresDrugsStatus.NOMER);
        } else {
            qw.lambda().eq(DrugsModel::getStatus, PresConstants.PresDrugsStatus.NOMER).and(StringUtils.isNotBlank(keyword), t -> t.like(DrugsModel::getHerbName, keyword).or().like(DrugsModel::getAlias, keyword).or().like(DrugsModel::getHerbNamePinyin, keyword).or().like(DrugsModel::getAliasPinyin, keyword));
        }

        List<DrugsModel> list = list(qw);
        return list;
    }

    /**
     * 设置拼音字段, 数据用,
     */
    @Override
    public void setDrugsPinyin() {
        List<DrugsModel> list = list();
        for (DrugsModel mo : list) {
            mo.setHerbNamePinyin(PinYinUtils.chineseToPinyinSell(mo.getHerbName()));
            mo.setAliasPinyin(PinYinUtils.chineseToPinyinSell(mo.getAlias()));
        }
        updateBatchById(list);
    }

    /**
     * 分页查询药材
     *
     * @param req
     * @return
     */
    @Override
    public Page<DrugsModelPageRes> getDrugsModelPage(PresPageReq req) {
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo().get();
        Page<DrugsModelPageRes> page = req.pagePojo();
        req.setPharFlag(pharmacyService.getPharmacyFlag(req.getPharmacyId()));
        if (!StringUtils.isBlank(req.getStatus())) {
            req.setStatusStr(req.getStatus().split(","));
        }
        if (loginInfo.getType() == LoginInfo.UserType.PHAR) {
            req.setPharmacyId(loginInfo.getPharId());
        }
        if (loginInfo.getType() == LoginInfo.UserType.DOCTOR) {
            //医生只能查询上架的药品
            req.setStatusStr(new String[]{String.valueOf(PresConstants.ModelDrugsStatus.NOMER)});
        }
        page = getBaseMapper().getDrugsModelPage(page, req);
        Integer discount = drugsDiscountService.getDrugsDiscount(loginInfo.getId(), loginInfo.getType());
        for (DrugsModelPageRes item : page.getRecords()) {
            item.setDiscountPrice(drugsDiscountService.computeDiscountPrice(BigDecimal.valueOf(item.getPrice()), discount).doubleValue());
        }
        return page;
    }

    /**
     * 添加药材
     *
     * @param req
     */
    @Override
    public void addDrugsModel(DrugsModelAddReq req) {
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo().get();
        QueryWrapper<DrugsModel> qw = new QueryWrapper<>();

        qw.lambda().eq(DrugsModel::getHerbName, req.getHerbName()).ne(DrugsModel::getStatus, PresConstants.ModelDrugsStatus.DEL).eq(DrugsModel::getPharId, loginInfo.getPharId());
        int num = count(qw);
        if (num > 0) {
            throw new ZekeException("药品名已存在");
        }
        if (!StringUtils.isBlank(req.getDrugnum())) {
            qw = new QueryWrapper<>();
            qw.lambda().eq(DrugsModel::getDrugnum, req.getDrugnum()).ne(DrugsModel::getStatus, PresConstants.ModelDrugsStatus.DEL).eq(DrugsModel::getPharId, loginInfo.getPharId());
            num = count(qw);
            if (num > 0) {
                throw new ZekeException("药品编码已存在");
            }
        } else {
            String drugNum = SerialNumberUtils.getInstance().drugsNumTenSerialNumber(redisTemplate);
            while (true) {
                QueryWrapper<DrugsModel> qws = new QueryWrapper<>();
                qws.lambda().eq(DrugsModel::getDrugnum, drugNum);
                List<DrugsModel> card = list(qws);
                if (card == null || card.isEmpty()) {
                    break;
                }
                drugNum = SerialNumberUtils.getInstance().drugsNumTenSerialNumber(redisTemplate);
            }
            req.setDrugnum(drugNum);
        }
        Integer flag = pharmacyService.getPharmacyFlag(loginInfo.getPharId());
        DrugsModel drugsModel = new DrugsModel();
        BeanUtils.copyProperties(req, drugsModel);
        drugsModel.setStatus(PresConstants.ModelDrugsStatus.NOMER);
        drugsModel.setCreateDate(LocalDateTime.now());
        drugsModel.setOperId(loginInfo.getId());
        drugsModel.setPharId(loginInfo.getPharId());
        //药品转繁体
        drugsModel.setHerbNameTraditional(ZhConverterUtil.toTraditional(drugsModel.getHerbName()));
        drugsModel.setHerbNamePinyin(PinYinUtils.chineseToPinyinSell(drugsModel.getHerbName()));
        drugsModel.setAliasPinyin(PinYinUtils.chineseToPinyinSell(drugsModel.getAlias()));
        drugsModel.setPrice(drugsModel.getPrice().multiply(new BigDecimal(100)));
        drugsModel.setQty(new BigDecimal(0));
        if (drugsModel.getOriginalPrice() != null) {
            drugsModel.setOriginalPrice(drugsModel.getOriginalPrice().multiply(new BigDecimal(100)));
        }
//        //TODO 公用药房需要有折扣价格
//        if (flag != PharConstants.Flag.STORE && flag != PharConstants.Flag.NOT) {
//            if (ObjectUtil.isNull(req.getPublicPrice())) {
//                throw new ZekeException("折扣价格不能为空");
//            }
//            drugsModel.setPublicPrice(req.getPublicPrice().multiply(new BigDecimal(100)));
//        }
        drugsModel.setPharFlag(flag);
        boolean i = save(drugsModel);
        if (!i) {
            throw new ZekeException(ZkExceptionEnum.ADD_ERROR);
        }
    }

    /**
     * 修改药品数据
     *
     * @param req
     */
    @Override
    public void updateDrugsModel(DrugsModelUpdateReq req) {
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo().get();
        DrugsModel drugsModel = getById(req.getId());
        if (drugsModel == null) {
            throw new ZekeException("药品不存在");
        }
        //修改了药品名,要查询是否存在
        if (!drugsModel.getHerbName().equals(req.getHerbName())) {
            QueryWrapper<DrugsModel> qw = new QueryWrapper<>();
            qw.lambda().eq(DrugsModel::getHerbName, req.getHerbName()).eq(DrugsModel::getPharId, loginInfo.getPharId()).eq(DrugsModel::getStatus, PresConstants.ModelDrugsStatus.NOMER);
            DrugsModel model = getOne(qw);
            if (model != null) {
                throw new ZekeException("药品名已存在");
            }
        }
        if (StringUtils.isBlank(req.getDrugnum())) {
            String drugNum = SerialNumberUtils.getInstance().drugsNumTenSerialNumber(redisTemplate);
            while (true) {
                QueryWrapper<DrugsModel> qws = new QueryWrapper<>();
                qws.lambda().eq(DrugsModel::getDrugnum, drugNum);
                List<DrugsModel> card = list(qws);
                if (card == null || card.isEmpty()) {
                    break;
                }
                drugNum = SerialNumberUtils.getInstance().medSerialNumber(redisTemplate);
            }
            req.setDrugnum(drugNum);
        } else {
            //修改了药品编码,要查询是否存在
            if (!drugsModel.getDrugnum().equals(req.getDrugnum())) {
                QueryWrapper<DrugsModel> qw = new QueryWrapper<>();
                qw.lambda().eq(DrugsModel::getDrugnum, req.getDrugnum()).eq(DrugsModel::getPharId, loginInfo.getPharId()).ne(DrugsModel::getStatus, PresConstants.ModelDrugsStatus.DEL);
                DrugsModel model = getOne(qw);
                if (model != null) {
                    throw new ZekeException("药品编码已存在");
                }
            }
        }
        //TODO 公用药房需要有折扣价格
//        Integer flag = pharmacyService.getPharmacyFlag(loginInfo.getPharId());
//        if (flag != PharConstants.Flag.STORE && flag != PharConstants.Flag.NOT) {
//            if (ObjectUtil.isNull(req.getPublicPrice())) {
//                throw new ZekeException("折扣价格不能为空");
//            }
//            drugsModel.setPublicPrice(req.getPublicPrice().multiply(new BigDecimal(100)));
//        }
        BeanUtils.copyProperties(req, drugsModel);
        drugsModel.setHerbNameTraditional(ZhConverterUtil.toTraditional(drugsModel.getHerbName()));
        drugsModel.setHerbNamePinyin(PinYinUtils.chineseToPinyinSell(drugsModel.getHerbName()));
        drugsModel.setAliasPinyin(PinYinUtils.chineseToPinyinSell(drugsModel.getAlias()));
        drugsModel.setPrice(drugsModel.getPrice().multiply(new BigDecimal(100)));
        if (drugsModel.getOriginalPrice() != null) {
            drugsModel.setOriginalPrice(drugsModel.getOriginalPrice().multiply(new BigDecimal(100)));
        }
        boolean i = updateById(drugsModel);
        if (!i) {
            throw new ZekeException(ZkExceptionEnum.ADD_ERROR);
        }

    }


    /**
     * 修改药品状态
     *
     * @param id
     * @param status
     */
    @Override
    public void updateStatusDrugsModel(Integer id, Integer status) {
        DrugsModel drugsModel = getById(id);
        if (drugsModel == null) {
            throw new ZekeException(400, "药品不存在");
        }
        if (!ObjectUtils.refrect(PresConstants.ModelDrugsStatus.class, status)) {
            throw new ZekeException(ZkExceptionEnum.STATUS_DATA_ERROR);
        }
        if (drugsModel.getStatus().equals(status)) {
            return;
        }
        drugsModel.setStatus(status);
        boolean i = updateById(drugsModel);
        if (!i) {
            throw new ZekeException(ZkExceptionEnum.UPDATE_ERROR);
        }
    }

    /**
     * 通过名字批量查询药材信息
     *
     * @param names
     * @param pharId
     * @return
     */
    @Override
    public Map<String, Object> drugsModelListByNameAndPharId(String names, Integer pharId) {
        if (pharId == null) {
            pharId = 1;
        }
        Integer pharFlag = pharmacyService.getPharmacyFlag(pharId);
        Map<String, Object> maps = new HashMap<>();
        Map<String, List<DrugsModelInfoListRes>> map = new HashMap<>();
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo().get();
        Integer discount = drugsDiscountService.getDrugsDiscount(loginInfo.getId(), loginInfo.getType());
        if (names.contains(",")) {
            String[] split = names.split(",");
            for (String name : split) {
                List<DrugsModelInfoListRes> list = getBaseMapper().queryDrugsListByNameAndPharId(pharId, pharFlag, name);
                for (DrugsModelInfoListRes item : list) {
                    item.setDiscountPrice(drugsDiscountService.computeDiscountPrice(BigDecimal.valueOf(item.getPrice()), discount).doubleValue());
                }
                map.put(name, list);
            }
        } else {
            List<DrugsModelInfoListRes> list = getBaseMapper().queryDrugsListByNameAndPharId(pharId, pharFlag, names);
            for (DrugsModelInfoListRes item : list) {
                item.setDiscountPrice(drugsDiscountService.computeDiscountPrice(BigDecimal.valueOf(item.getPrice()), discount).doubleValue());
            }
            map.put(names, list);
        }
        maps.put("list", map);
        return maps;
    }


    /**
     * 查询不存在的药品, 通过药品编号列表
     *
     * @param nums 要识别的药品
     * @return
     */
    @Override
    public void getDrugsNoExistByDrugNum(List<String> nums) {
        if (nums.isEmpty()) {
            return;
        }
        QueryWrapper<DrugsModel> qw = new QueryWrapper<>();
        qw.lambda().ne(DrugsModel::getStatus, PresConstants.ModelDrugsStatus.DEL).in(DrugsModel::getDrugnum, nums);
        List<DrugsModel> drugsModels = list(qw);
        //存在的药品
        List<String> exist = drugsModels.stream().map(DrugsModel::getDrugnum).collect(Collectors.toList());
        nums.removeAll(exist);
        if (!exist.isEmpty()) {
            throw new ZekeException(400, "以下药品编码不存在:" + StringUtils.join((nums), ","));
        }
    }

    /**
     * 导入中药材详细信息数据 第三方药房自定义excel导入
     *
     * @param file     excel文件
     * @param pharFlag 药房标识
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void importExcelDrugs(MultipartFile file, String pharFlag) {
        switch (pharFlag) {
            case "dsl":
                dslAddDrugModel(file);
                break;
            case "km":
                kmAddDrugModel(file);
                break;
            case "xx":
                xxAddOrUpdateDrugModel();
                break;
            default:
                hjtAddDrugModel(file);
                break;
        }
    }

    /**
     * @param file:
     * @return void
     * @description excel导入平台药房药材数据
     * @author czg
     * @date 2023/4/18 14:40
     */
    @Override
    public Map<String, String> importExcelPharDrugs(MultipartFile file) {
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo().get();
        List<ExcelAddDrugModel> list;
        try {
            if (file == null) {
                throw new ZekeException("请上传文件");
            }
            list = ExtUtils.importExcel(file, 1, 1, ExcelAddDrugModel.class);
        } catch (IOException e) {
            e.printStackTrace();
            throw new ZekeException("解析Excel失败");
        }
        if (list == null || list.isEmpty()) {
            throw new ZekeException("药品数据为空");
        }
        List<String> failModel = new ArrayList<>();
        //查询药房标识
        Integer pharFlag = pharmacyService.getPharmacyFlag(loginInfo.getPharId());
        for (ExcelAddDrugModel model : list) {
            String verifyStr = ValidatorUtils.verifyStr(model, ExcelAddDrugModel.class);
            if (!StringUtils.isBlank(verifyStr)) {
                failModel.add(model.getHerbName());
                continue;
            }
//            //TODO 公用药房需要有折扣价格
//            Integer flag = pharmacyService.getPharmacyFlag(loginInfo.getPharId());
//            if (flag != PharConstants.Flag.STORE && flag != PharConstants.Flag.NOT) {
//                if (ObjectUtil.isNull(model.getPublicPrice())) {
//                    failModel.add(model.getHerbName());
//                    continue;
//                }
//            }
            QueryWrapper<DrugsModel> wrapper = new QueryWrapper<>();
            wrapper.lambda().ne(DrugsModel::getStatus, PresConstants.PresDrugsStatus.DEL).eq(DrugsModel::getPharId, loginInfo.getPharId()).and(t -> {
                t.eq(DrugsModel::getDrugnum, model.getDrugnum()).or().eq(DrugsModel::getHerbName, model.getHerbName());
            });
            DrugsModel one = getOne(wrapper);
            if (one != null) {
                failModel.add(model.getHerbName());
                continue;
            }
            one = new DrugsModel();
            BeanUtils.copyProperties(model, one);
            if (StringUtils.isBlank(model.getDrugnum())) {
                String drugNum = SerialNumberUtils.getInstance().drugsNumTenSerialNumber(redisTemplate);
                one.setDrugnum(drugNum);
            }
            //药品转繁体
            one.setHerbNameTraditional(ZhConverterUtil.toTraditional(model.getHerbName()));
            one.setHerbNamePinyin(PinYinUtils.chineseToPinyinSell(model.getHerbName()));
            one.setType(DrugsConstants.Type.CH_DRUG);
            one.setCreateDate(LocalDateTime.now());
            one.setStatus(PresConstants.PresDrugsStatus.NOMER);
            one.setOperId(loginInfo.getId());
            one.setPharId(loginInfo.getPharId());
            one.setPrice(one.getPrice().multiply(new BigDecimal(100)));
            one.setQty(new BigDecimal(0));
            one.setPharFlag(pharFlag);
            if (one.getOriginalPrice() != null) {
                one.setOriginalPrice(one.getOriginalPrice().multiply(new BigDecimal(100)));
            }
//            if (flag != PharConstants.Flag.STORE && flag != PharConstants.Flag.NOT && one.getPublicPrice() != null) {
//                one.setPublicPrice(one.getPublicPrice().multiply(new BigDecimal(100)));
//            }
            boolean save = save(one);
            if (!save) {
                failModel.add(one.getHerbName());
            }
        }
        Map<String, String> result = new HashMap<>();
        result.put("success", list.size() - failModel.size() + "");
        result.put("fail", failModel.size() + "");
        String failMsg = "";
        if (CollectionUtil.isNotEmpty(failModel)) {
            failMsg = StringUtils.join(failModel, ",");
        }
        result.put("failMsg", failMsg);
        return result;
    }

    /**
     * @param req:
     * @return Page<DrugsModelPharPageRes>
     * @description 药房后台查询药材编码
     * @author czg
     * @date 2023/4/18 16:15
     */
    @Override
    public Page<DrugsModelManagePageRes> getDrugsModelManagePage(PresPageReq req) {
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo().get();

        if (!StringUtils.isBlank(req.getStatus())) {
            req.setStatusStr(req.getStatus().split(","));
        }
        Page<DrugsModelManagePageRes> page = req.pagePojo();
        if (loginInfo.getType() == LoginInfo.UserType.PHAR) {
            req.setPharmacyId(loginInfo.getPharId());
        }
        page = getBaseMapper().getDrugsModelManagePage(page, req);

        return page;
    }

    /**
     * @param :
     * @return void
     * @description 药材数据更新到es
     * @author czg
     * @date 2023/5/19 14:48
     */
    @Override
    public void drugsEsUpdate() {
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo().get();
        List<DrugsModelPageRes> esModelList = new ArrayList<>();
        esModelList = getBaseMapper().getDrugsModelList();
        Integer discount = drugsDiscountService.getDrugsDiscount(loginInfo.getId(), loginInfo.getType());
        for (DrugsModelPageRes item : esModelList) {
            item.setDiscountPrice(drugsDiscountService.computeDiscountPrice(BigDecimal.valueOf(item.getPrice()), discount).doubleValue());
        }
        if (esModelList != null && !esModelList.isEmpty()) {
            ResponseEntity<Boolean> booleanResponseEntity = searchFeignService.drugsEsSave(esModelList);
            Boolean body = booleanResponseEntity.getBody();
            if (body) {
                throw new ZekeException("同步药材到es失败");
            }
        }
    }

    @Override
    public void setDrugTraditional() {
        List<DrugsModel> list = list();
        for (DrugsModel mo : list) {
            mo.setHerbNameTraditional(ZhConverterUtil.toTraditional(mo.getHerbName()));
            if (StringUtils.isNotBlank(mo.getAlias())) {
                mo.setAliasTraditional(ZhConverterUtil.toTraditional(mo.getAlias()));
            }
        }
        updateBatchById(list);
    }

    /**
     * 同步一方制药颗粒药材数据
     *
     * @param list
     * @param pharmacyId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void syncYfKlDrugInfo(List<ReturnQueryDrugKlResultDTO> list, Integer pharmacyId) {
        UpdateWrapper<DrugsModel> uw = new UpdateWrapper<>();
        uw.lambda().eq(DrugsModel::getPharId, pharmacyId).eq(DrugsModel::getPharFlag, PharConstants.Flag.YF);
        uw.lambda().set(DrugsModel::getStatus, PresConstants.PresDrugsStatus.DEL);
        update(uw);
        QueryWrapper<DrugsModel> qw = new QueryWrapper<>();
        List<DrugsModel> addOrUpdateList = new ArrayList<>(list.size());
        for (ReturnQueryDrugKlResultDTO item : list) {
            qw.clear();
            qw.lambda().eq(DrugsModel::getDrugnum, item.getDrugId());
            qw.lambda().eq(DrugsModel::getDrugId, item.getOnlyId());
            qw.lambda().select(DrugsModel::getId);
            DrugsModel temp = getOne(qw);
            DrugsModel addOrUpdate = new DrugsModel();
            if (temp != null) {
                addOrUpdate.setId(temp.getId());
            }
            addOrUpdate.setDrugnum(item.getDrugId());
            addOrUpdate.setDrugId(item.getOnlyId());
            addOrUpdate.setHerbName(item.getName());
            addOrUpdate.setHerbNamePinyin(item.getSpell());
            addOrUpdate.setHerbNameTraditional(ZhConverterUtil.toTraditional(item.getName()));
            addOrUpdate.setPharId(pharmacyId);
            addOrUpdate.setPharFlag(PharConstants.Flag.YF);
            addOrUpdate.setUseUnit("g");
            addOrUpdate.setKlType(item.getType());
            addOrUpdate.setKlPrice(BigDecimalUtils.multiply(new BigDecimal(item.getGPrice()), BigDecimal.valueOf(100)));
            addOrUpdate.setStatus(PresConstants.PresDrugsStatus.DEL);
            addOrUpdate.setCreateDate(LocalDateTime.now());
            addOrUpdateList.add(addOrUpdate);
        }
        saveOrUpdateBatch(addOrUpdateList);
    }

    /**
     * 导入一方制药颗粒药材价格
     *
     * @param file
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void importYfKlDrugPrice(MultipartFile file) {
        QueryWrapper<Pharmacy> ql = new QueryWrapper<>();
        ql.lambda().eq(Pharmacy::getFlag, PharConstants.Flag.YF).eq(Pharmacy::getStatus, PharConstants.Status.NOMER);
        Pharmacy pharmacy = pharmacyService.getOne(ql);
        if (pharmacy == null) {
            throw new ZekeException(400, "药房不存在");
        }
        List<YfKlDrugModel> list;
        try {
            if (file == null) {
                throw new ZekeException(400, "请上传文件");
            }
            list = ExtUtils.importExcel(file, 0, 1, YfKlDrugModel.class);
        } catch (IOException e) {
            e.printStackTrace();
            throw new ZekeException(400, "解析Excel失败");
        }
        List<DrugsModel> updateList = new ArrayList<>(list.size());
        QueryWrapper<DrugsModel> qw = new QueryWrapper<>();
        for (YfKlDrugModel item : list) {
            qw.clear();
            qw.lambda().eq(DrugsModel::getPharId, pharmacy.getId());
            qw.lambda().eq(DrugsModel::getHerbName, item.getHerbName());
            qw.lambda().select(DrugsModel::getId);
            DrugsModel drugsModel = getOne(qw);
            if (drugsModel == null) {
                qw.clear();
                qw.lambda().eq(DrugsModel::getPharId, pharmacy.getId());
                qw.lambda().eq(DrugsModel::getHerbName, item.getOrHerbName());
                qw.lambda().select(DrugsModel::getId);
                drugsModel = getOne(qw);
                if (drugsModel == null) {
                    continue;
                }
            }
            drugsModel.setPrice(BigDecimalUtils.multiply(item.getPrice(), BigDecimal.valueOf(100)));
            drugsModel.setOriginalPrice(BigDecimalUtils.multiply(item.getOrPrice(), BigDecimal.valueOf(100)));
            drugsModel.setStatus(PresConstants.PresDrugsStatus.NOMER);
            updateList.add(drugsModel);
        }
        updateBatchById(updateList);
    }

    /**
     * 同步华润三九药材数据
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void syncHrDrugInfo(List<ReturnDrugList> list, Integer pharmacyId) {
        UpdateWrapper<DrugsModel> uw = new UpdateWrapper<>();
        uw.lambda().eq(DrugsModel::getPharId, pharmacyId).eq(DrugsModel::getPharFlag, PharConstants.Flag.HR);
        uw.lambda().set(DrugsModel::getStatus, PresConstants.PresDrugsStatus.DEL);
        update(uw);
        QueryWrapper<DrugsModel> qw = new QueryWrapper<>();
        List<DrugsModel> addOrUpdateList = new ArrayList<>(list.size());
        for (ReturnDrugList item : list) {
            //此版本导入饮片药品相关数据
            if (item.getGranuleName().contains("(颗粒)")) {
                continue;
            }
            qw.clear();
            qw.lambda().eq(DrugsModel::getDrugnum, item.getGranuleId());
            qw.lambda().eq(DrugsModel::getPharFlag, PharConstants.Flag.HR);
            qw.lambda().select(DrugsModel::getId);
            DrugsModel temp = getOne(qw);
            DrugsModel addOrUpdate = new DrugsModel();
            if (temp != null) {
                addOrUpdate.setId(temp.getId());
            }
            addOrUpdate.setDrugnum(item.getGranuleId());
            addOrUpdate.setPharId(pharmacyId);
            addOrUpdate.setPharFlag(PharConstants.Flag.HR);
            addOrUpdate.setUseUnit("g");
            addOrUpdate.setHerbName(item.getGranuleName());
            addOrUpdate.setHerbNamePinyin(PinYinUtils.chineseToPinyinSell(item.getGranuleName()));
            addOrUpdate.setHerbNameTraditional(ZhConverterUtil.toTraditional(item.getGranuleName()));
            addOrUpdate.setType(1);
            addOrUpdate.setStatus(PresConstants.PresDrugsStatus.NOMER);
            addOrUpdate.setCreateDate(LocalDateTime.now());
            addOrUpdateList.add(addOrUpdate);
        }
        if (CollectionUtil.isNotEmpty(addOrUpdateList)) {
            saveOrUpdateBatch(addOrUpdateList);
        }
    }

    /**
     * 同步华润药品价格
     */
    @Override
    public void importHrDrugPrice(MultipartFile file) {
        QueryWrapper<Pharmacy> ql = new QueryWrapper<>();
        ql.lambda().eq(Pharmacy::getFlag, PharConstants.Flag.HR).eq(Pharmacy::getStatus, PharConstants.Status.NOMER);
        Pharmacy pharmacy = pharmacyService.getOne(ql);
        if (pharmacy == null) {
            throw new ZekeException(400, "药房不存在");
        }
        List<HrDrugModel> list;
        try {
            if (file == null) {
                throw new ZekeException(400, "请上传文件");
            }
            list = ExtUtils.importExcel(file, 2, 1, HrDrugModel.class);
        } catch (IOException e) {
            e.printStackTrace();
            throw new ZekeException(400, "解析Excel失败");
        }
        BigDecimal zero = new BigDecimal(BigInteger.ZERO);
        List<DrugsModel> updateList = new ArrayList<>(list.size());
        QueryWrapper<DrugsModel> qw = new QueryWrapper<>();
        for (HrDrugModel item : list) {
            qw.clear();
            qw.lambda().eq(DrugsModel::getPharId, pharmacy.getId());
            qw.lambda().eq(DrugsModel::getDrugnum, item.getDrugNum());
            qw.lambda().select(DrugsModel::getId);
            DrugsModel drugsModel = getOne(qw);
            if (drugsModel == null) {
                continue;
            }
            if (item.getPrice().compareTo(zero) == 0 && item.getOriginalPrice().compareTo(zero) == 0) {
                drugsModel.setPrice(new BigDecimal(0));
                drugsModel.setOriginalPrice(new BigDecimal(0));
                drugsModel.setStatus(PresConstants.PresDrugsStatus.DEL);
            } else {
                drugsModel.setPrice(BigDecimalUtils.multiply(item.getPrice(), BigDecimal.valueOf(100)));
                drugsModel.setOriginalPrice(BigDecimalUtils.multiply(item.getOriginalPrice(), BigDecimal.valueOf(100)));
                drugsModel.setStatus(PresConstants.PresDrugsStatus.NOMER);
            }
            updateList.add(drugsModel);
        }
        updateBatchById(updateList);
    }

    /**
     * list去重
     */
    private <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
        Map<Object, Boolean> seen = new ConcurrentHashMap<>();
        return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
    }

    /**
     * @param list: 药房返回的药材列表
     * @param id:   药房ID
     * @return void
     * @description 同步和顺堂药材目录
     * @author czg
     * @date 2023/11/7 16:37
     */
    @Override
    public void syncHstDrugInfo(List<HstDrugsResDTO.DrugList> list, Integer id) {
        if (list == null || list.isEmpty()) {
            return;
        }
        //和顺堂会有重复药品编码的药材, 规格不一样, 去重, 要一种规格即可
        list = list.stream().filter(distinctByKey(HstDrugsResDTO.DrugList::getDrug_code)).collect(Collectors.toList());
        UpdateWrapper<DrugsModel> uw = new UpdateWrapper<>();
        uw.lambda().eq(DrugsModel::getPharId, id).eq(DrugsModel::getPharFlag, PharConstants.Flag.HR);
        uw.lambda().set(DrugsModel::getStatus, PresConstants.PresDrugsStatus.DEL);
        update(uw);
        QueryWrapper<DrugsModel> qw = new QueryWrapper<>();
        List<DrugsModel> addOrUpdateList = new ArrayList<>(list.size());
        for (HstDrugsResDTO.DrugList item : list) {

            qw.clear();
            qw.lambda().eq(DrugsModel::getDrugnum, item.getDrug_code());
            qw.lambda().eq(DrugsModel::getPharFlag, PharConstants.Flag.HST);
            qw.lambda().select(DrugsModel::getId);
            DrugsModel temp = getOne(qw);
            DrugsModel addOrUpdate = new DrugsModel();
            if (temp != null) {
                addOrUpdate.setId(temp.getId());
            }
            addOrUpdate.setDrugnum(item.getDrug_code());
            addOrUpdate.setPharId(id);
            addOrUpdate.setPharFlag(PharConstants.Flag.HST);
            addOrUpdate.setUseUnit(item.getDrug_unit());
            addOrUpdate.setHerbName(item.getDrug_name());
            addOrUpdate.setHerbNamePinyin(PinYinUtils.chineseToPinyinSell(item.getDrug_name()));
            addOrUpdate.setHerbNameTraditional(ZhConverterUtil.toTraditional(item.getDrug_name()));
            addOrUpdate.setType(1);
            addOrUpdate.setStatus(PresConstants.PresDrugsStatus.NOMER);
            addOrUpdate.setCreateDate(LocalDateTime.now());
            addOrUpdate.setSpecification(item.getDrug_spec());
            BigDecimal divide = BigDecimal.valueOf(item.getDrug_price()).multiply(new BigDecimal(100));
            addOrUpdate.setOriginalPrice(divide);
            addOrUpdateList.add(addOrUpdate);
        }
        if (CollectionUtil.isNotEmpty(addOrUpdateList)) {
            saveOrUpdateBatch(addOrUpdateList);
        }
    }

    /**
     * @param file:
     * @return void
     * @author czg
     * @description 宏济堂药房价格名录导入数据库
     * @date 2022/12/19 14:38
     */
    public void hjtAddDrugModel(MultipartFile file) {
        QueryWrapper<Pharmacy> ql = new QueryWrapper<>();
        ql.lambda().eq(Pharmacy::getFlag, PharConstants.Flag.HJT).eq(Pharmacy::getStatus, PharConstants.Status.NOMER);
        Pharmacy pharmacy = pharmacyService.getOne(ql);
        if (pharmacy == null) {
            throw new ZekeException(400, "药房不存在");
        }
        List<HjtDrugModel> list;
        try {
            if (file == null) {
                throw new ZekeException(400, "请上传文件");
            }
            list = ExtUtils.importExcel(file, 1, 1, HjtDrugModel.class);
        } catch (IOException e) {
            e.printStackTrace();
            throw new ZekeException(400, "解析Excel失败");
        }
        log.info("list:{}:", list);
        UpdateWrapper<DrugsModel> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda().set(DrugsModel::getStatus, PresConstants.PresDrugsStatus.DEL).eq(DrugsModel::getPharId, pharmacy.getId());
        update(updateWrapper);
        List<DrugsModel> listExists = new LinkedList<>();
        List<DrugsModel> listNew = new LinkedList<>();
        for (HjtDrugModel model : list) {
            QueryWrapper<DrugsModel> qw = new QueryWrapper<>();
            qw.lambda().eq(DrugsModel::getHerbName, model.getHerbName()).eq(DrugsModel::getPharId, pharmacy.getId()).eq(DrugsModel::getStatus, PharConstants.Status.NOMER);
            DrugsModel drugsModel = getOne(qw);
            if (drugsModel != null) {
                drugsModel.setStatus(PresConstants.PresDrugsStatus.NOMER);
                drugsModel.setDrugnum(model.getDrugnum());
                drugsModel.setOriginalPrice(model.getOrPrice().multiply(BigDecimal.valueOf(100)));
                drugsModel.setPrice(model.getPrice().multiply(BigDecimal.valueOf(100)));
                drugsModel.setUseUnit(model.getUseUnit());
                listExists.add(drugsModel);
            } else {
                drugsModel = new DrugsModel();
                drugsModel.setStatus(PresConstants.PresDrugsStatus.NOMER);
                drugsModel.setDrugnum(model.getDrugnum());
                drugsModel.setOriginalPrice(model.getOrPrice().multiply(BigDecimal.valueOf(100)));
                drugsModel.setPrice(model.getPrice().multiply(BigDecimal.valueOf(100)));
                drugsModel.setUseUnit(model.getUseUnit());
                drugsModel.setCreateDate(LocalDateTime.now());
                drugsModel.setHerbName(model.getHerbName());
                drugsModel.setHerbNamePinyin(PinYinUtils.chineseToPinyinSell(drugsModel.getHerbName()));
                drugsModel.setPharId(1);
                drugsModel.setPharFlag(1);
                drugsModel.setType(1);
                listNew.add(drugsModel);
            }
        }
        if (!listExists.isEmpty()) {
            getBaseMapper().mysqlInsertOrUpdateBath(listExists);
        }
        if (!listNew.isEmpty()) {
            getBaseMapper().insertBatchSomeColumn(listNew);
        }
    }

    /**
     * @param file:
     * @return void
     * @author czg
     * @description 大参林药房价格名录导入数据库
     * @date 2022/12/19 14:38
     */
    public void dslAddDrugModel(MultipartFile file) {
        QueryWrapper<Pharmacy> ql = new QueryWrapper<>();
        List<DslDrugModel> list;
        ql.lambda().eq(Pharmacy::getFlag, PharConstants.Flag.DSL).eq(Pharmacy::getStatus, PharConstants.Status.NOMER);
        Pharmacy pharmacy = pharmacyService.getOne(ql);
        if (pharmacy == null) {
            throw new ZekeException(400, "药房不存在");
        }
        try {
            if (file == null) {
                throw new ZekeException(400, "请上传文件");
            }
            list = ExtUtils.importExcel(file, 0, 1, DslDrugModel.class);
        } catch (IOException e) {
            e.printStackTrace();
            throw new ZekeException(400, "解析Excel失败");
        }
        UpdateWrapper<DrugsModel> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda().set(DrugsModel::getStatus, PresConstants.PresDrugsStatus.DEL).eq(DrugsModel::getPharId, pharmacy.getId());
        update(updateWrapper);
        List<DrugsModel> listNew = new LinkedList<>();
        for (DslDrugModel model : list) {
            QueryWrapper<DrugsModel> qw = new QueryWrapper<>();
            qw.lambda().eq(DrugsModel::getHerbName, model.getHerbName()).eq(DrugsModel::getPharId, pharmacy.getId()).eq(DrugsModel::getStatus, PharConstants.Status.NOMER).last("limit 1");
            DrugsModel drugsModel = getOne(qw);
            if (drugsModel != null) {
                DrugsModel newModel = new DrugsModel();
                BeanUtils.copyProperties(drugsModel, newModel);
                newModel.setStatus(PresConstants.PresDrugsStatus.NOMER);
                newModel.setDrugnum(model.getNum());
                newModel.setId(null);
                if ("kg".equals(model.getUseUnit())) {
                    newModel.setPrice(BigDecimalUtils.divide(model.getPrice().multiply(new BigDecimal(100)), BigDecimal.valueOf(1000), 3));
                    newModel.setOriginalPrice(BigDecimalUtils.divide(model.getOriginalPrice().multiply(new BigDecimal(100)), BigDecimal.valueOf(1000), 3));
                    newModel.setUseUnit("g");
                } else {
                    newModel.setUseUnit(model.getUseUnit());
                    newModel.setPrice(model.getPrice().multiply(new BigDecimal(100)));
                    newModel.setOriginalPrice(model.getOriginalPrice().multiply(new BigDecimal(100)));
                }
                newModel.setHerbName(model.getHerbName());
                newModel.setHerbNamePinyin(PinYinUtils.chineseToPinyinSell(drugsModel.getHerbName()));
                newModel.setPharId(pharmacy.getId());
                drugsModel.setPharFlag(pharmacy.getFlag());
                newModel.setCreateDate(LocalDateTime.now());
                newModel.setType(1);
                drugsModel.setSpecification(model.getSpecification());
                listNew.add(newModel);
            } else {
                drugsModel = new DrugsModel();
                drugsModel.setStatus(PresConstants.PresDrugsStatus.NOMER);
                drugsModel.setDrugnum(model.getNum());
                if ("kg".equals(model.getUseUnit())) {
                    drugsModel.setPrice(BigDecimalUtils.divide(model.getPrice().multiply(new BigDecimal(100)), BigDecimal.valueOf(1000), 3));
                    drugsModel.setOriginalPrice(BigDecimalUtils.divide(model.getOriginalPrice().multiply(new BigDecimal(100)), BigDecimal.valueOf(1000), 3));
                    drugsModel.setUseUnit("g");
                } else {
                    drugsModel.setPrice(model.getPrice().multiply(new BigDecimal(100)));
                    drugsModel.setOriginalPrice(model.getOriginalPrice().multiply(new BigDecimal(100)));
                    drugsModel.setUseUnit(model.getUseUnit());
                }
                drugsModel.setCreateDate(LocalDateTime.now());
                drugsModel.setHerbName(model.getHerbName());
                drugsModel.setHerbNamePinyin(PinYinUtils.chineseToPinyinSell(drugsModel.getHerbName()));
                drugsModel.setPharId(pharmacy.getId());
                drugsModel.setPharFlag(pharmacy.getFlag());
                drugsModel.setType(1);
                drugsModel.setSpecification(model.getSpecification());
                listNew.add(drugsModel);
            }
        }
        if (!listNew.isEmpty()) {
            getBaseMapper().insertBatchSomeColumn(listNew);
        }
    }

    /**
     * @param file:
     * @return void
     * @author czg
     * @description 康美药房药品价格名录导入数据库
     * @date 2022/12/19 14:38
     */
    public void kmAddDrugModel(MultipartFile file) {
        QueryWrapper<Pharmacy> ql = new QueryWrapper<>();
        ql.lambda().eq(Pharmacy::getFlag, PharConstants.Flag.KM).eq(Pharmacy::getStatus, PharConstants.Status.NOMER).last("limit 1");
        Pharmacy pharmacy = pharmacyService.getOne(ql);
        if (pharmacy == null) {
            throw new ZekeException(400, "药房不存在");
        }
        List<KmDrugModel> list;
        try {
            if (file == null) {
                throw new ZekeException(400, "请上传文件");
            }
            list = ExtUtils.importExcel(file, 0, 1, KmDrugModel.class);
        } catch (IOException e) {
            e.printStackTrace();
            throw new ZekeException(400, "解析Excel失败");
        }
        Integer pharId = null;
        if (!list.isEmpty()) {
            pharId = list.get(0).getPharId();
        }
        pharId = pharId == null ? pharmacy.getId() : pharId;
        UpdateWrapper<DrugsModel> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda().set(DrugsModel::getStatus, PresConstants.PresDrugsStatus.DEL).eq(DrugsModel::getPharId, pharId);
        update(updateWrapper);
        QueryWrapper<DrugsModel> qw = new QueryWrapper<>();
        List<DrugsModel> saveOrUpdateList = new LinkedList<>();
        for (KmDrugModel item : list) {
            qw.clear();
            qw.lambda().eq(DrugsModel::getDrugnum, item.getNum()).eq(DrugsModel::getPharId, pharId);
            qw.lambda().select(DrugsModel::getId);
            DrugsModel temp = getOne(qw);
            DrugsModel drugsModel = new DrugsModel();
            if (temp != null) {
                drugsModel.setId(temp.getId());
            }
            drugsModel.setDrugnum(item.getNum());
            drugsModel.setHerbName(item.getHerbName());
            drugsModel.setHerbNamePinyin(PinYinUtils.chineseToPinyinSell(item.getHerbName()));
            drugsModel.setUseUnit(item.getUseUnit());
            drugsModel.setPrice(BigDecimalUtils.multiply(item.getPrice(), BigDecimal.valueOf(100)));
            drugsModel.setOriginalPrice(BigDecimalUtils.multiply(item.getOrPrice(), BigDecimal.valueOf(100)));
            drugsModel.setType(1);
            drugsModel.setStatus(PresConstants.PresDrugsStatus.NOMER);
            if (item.getPharId() != null) {
                drugsModel.setPharId(item.getPharId());
            } else {
                drugsModel.setPharId(pharmacy.getId());
            }
            drugsModel.setPharFlag(pharmacy.getFlag());
            drugsModel.setCreateDate(LocalDateTime.now());
            saveOrUpdateList.add(drugsModel);
        }
        if (!saveOrUpdateList.isEmpty()) {
            saveOrUpdateBatch(saveOrUpdateList);
        }
    }

    /**
     * @return void
     * @author czg
     * @description 香雪药房药品价格名录导入数据库
     * @date 2022/12/19 14:38
     */
    public void xxAddOrUpdateDrugModel() {
        QueryWrapper<Pharmacy> ql = new QueryWrapper<>();
        ql.lambda().eq(Pharmacy::getFlag, PharConstants.Flag.XX).eq(Pharmacy::getStatus, PharConstants.Status.NOMER);
        Pharmacy pharmacy = pharmacyService.getOne(ql);
        if (pharmacy == null) {
            throw new ZekeException(400, "药房不存在");
        }
        QueryWrapper<PharmacyDocking> q2 = new QueryWrapper<>();
        q2.lambda().eq(PharmacyDocking::getPharId, pharmacy.getId()).eq(PharmacyDocking::getStatus, PharConstants.DockingStatus.NOMER);
        PharmacyDocking pharmacyDocking = pharmacyDockingService.getOne(q2);
        String time = String.valueOf(System.currentTimeMillis());
        String sign = Md5Utils.md5Str(pharmacyDocking.getEncryptyKey(), pharmacyDocking.getMchId(), time);
        String url = "http://59.41.185.245:60980/orderplat/api/getDrugList?sign=%s&deptId=%s&time=%s";
        url = String.format(url, sign, pharmacyDocking.getMchId(), time);
        String result;
        try {
            result = HttpRequestUtils.get(url);
            log.info("result:{}", result);
        } catch (IOException e) {
            e.printStackTrace();
            throw new ZekeException(400, "请求药材数据错误");
        }
        ResultResDTO resDTO;
        List<XxDrugModel> list;
        try {
            resDTO = JSON.parseObject(result, ResultResDTO.class);
            list = JSON.parseArray(resDTO.getData(), XxDrugModel.class);
        } catch (Exception e) {
            throw new ZekeException(400, "药材数据转换错误");
        }
        UpdateWrapper<DrugsModel> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda().set(DrugsModel::getStatus, PresConstants.PresDrugsStatus.DEL).eq(DrugsModel::getPharId, pharmacy.getId());
        update(updateWrapper);
        List<DrugsModel> saveUpdateList = new LinkedList<>();
        QueryWrapper<DrugsModel> qw = new QueryWrapper<>();
        for (XxDrugModel item : list) {
            qw.clear();
            qw.lambda().or(t -> t.eq(DrugsModel::getDrugId, item.getId()).or().eq(DrugsModel::getDrugnum, item.getCode()));
            qw.lambda().select(DrugsModel::getId);
            DrugsModel temp = getOne(qw);
            DrugsModel drugsModel = new DrugsModel();
            if (temp != null) {
                drugsModel.setId(temp.getId());
            }
            drugsModel.setDrugnum(item.getCode());
            drugsModel.setHerbName(item.getName());
            drugsModel.setHerbNamePinyin(PinYinUtils.chineseToPinyinSell(item.getName()));
            drugsModel.setUseUnit(item.getUnit());
            drugsModel.setPrice(BigDecimalUtils.multiply(new BigDecimal(item.getYgprice()), BigDecimal.valueOf(100)));
            drugsModel.setType(1);
            drugsModel.setStatus(PresConstants.PresDrugsStatus.NOMER);
            drugsModel.setPharId(pharmacy.getId());
            drugsModel.setCreateDate(LocalDateTime.now());
            drugsModel.setDrugId(item.getId());
            saveUpdateList.add(drugsModel);
        }
        if (!saveUpdateList.isEmpty()) {
            saveOrUpdateBatch(saveUpdateList);
        }
    }
}
